//
// Created by zhuyijun on 2021/9/1.
//

#include <iostream>

using namespace std;

/**
 * 模版的友元分3累
 * 非模版友元
 * 约束模版友元，即友元的类型取决于类被实例化时的类型
 * 非约束模版友元，即友元的所有具体化都是累的每一个具体化的友元。
 * @return
 */
template<typename T>
class HasFriend {
private:
    T item;
    static int ct;
public:
    HasFriend(const T &i) : item(i) { ct++; }
    ~HasFriend(){ct--;}
    friend void counts();
    friend void reports(HasFriend<T> &);
};

template<typename T>
int HasFriend<T>::ct = 0;

void counts(){
    cout <<"int count: "<<HasFriend<int>::ct << "; ";
    cout <<"double count: " <<HasFriend<double>::ct << endl;
}

void reports(HasFriend<int> & hf){
    cout <<"HasFriend<int> : "<<hf.item << endl;
}
void reports(HasFriend<double> & hf){
    cout <<"HasFriend<double> : "<<hf.item << endl;
}

int main() {
    cout <<"No objects declared: ";
    counts();
    HasFriend<int> hfi1(10);
    cout <<"After hfi1 declared: ";
    counts();
    HasFriend<int> hfi2(20);
    cout <<"After hfi1 declared: ";
    counts();
    HasFriend<double> hfdb(10.5);
    cout <<"After hfdb declared: ";
    counts();
    reports(hfi1);
    reports(hfi2);
    reports(hfdb);
    return 0;
}

